home *** CD-ROM | disk | FTP | other *** search
/ Robotics & Artificial Int…3 (Professional Edition) / Robotics & Artificial Intelligence Tools 2003 (Professional Edition).iso / neural network tool and application / nsinstall.exe / data1.cab / CustomSolutionWizard_Files / ProjectShells / VCPPShell.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-08  |  28.0 KB  |  607 lines

  1. //===========================================================================
  2. // Custom Solution Wizard - Visual C++ Shell - Sample Functions
  3. //
  4. //---------------------------------------------------------------------------
  5. //    These files were created with the MFC AppWizard to illustrate how the
  6. //    sample NSLearningNetwork and NSRecallNetwork classes can be used to
  7. //  interact with a Custom Solution Wizard generated DLL for training
  8. //  or recall from a Visual C++ program.
  9. //---------------------------------------------------------------------------
  10. //    This program will compile and run without any further modification.
  11. //    It uses the training data taken from your original breadboard. This data
  12. //  was saved to two files: InputData.txt and DesiredData.txt during the DLL
  13. //  generation.
  14. //===========================================================================
  15.  
  16. //===========================================================================
  17. // Includes
  18. //===========================================================================
  19. #include "stdafx.h"
  20. #include <string.h>
  21. #include "VCPPShell.h"
  22. #include "NSNetwork.h"
  23. #include "Globals.h"
  24.  
  25. //===========================================================================
  26. // Debug handling generated by MFC AppWizard.
  27. //===========================================================================
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33.  
  34. //===========================================================================
  35. //===========================================================================
  36. // CLASS: CVCPPShellApp
  37. //===========================================================================
  38. //===========================================================================
  39.  
  40. //===========================================================================
  41. // Global declaration of application generated by MFC AppWizard.
  42. //===========================================================================
  43. CVCPPShellApp theApp;
  44.  
  45. //===========================================================================
  46. // CLASS: CVCPPShellApp            MESSAGE MAP
  47. //---------------------------------------------------------------------------
  48. // Note: This mapping was built by the MFC AppWizard.
  49. //===========================================================================
  50. BEGIN_MESSAGE_MAP(CVCPPShellApp, CWinApp)
  51.     //{{AFX_MSG_MAP(CVCPPShellApp)
  52.         // NOTE - the ClassWizard will add and remove mapping macros here.
  53.         //    DO NOT EDIT what you see in these blocks of generated code!
  54.     //}}AFX_MSG
  55.     ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  56. END_MESSAGE_MAP()
  57.  
  58. //===========================================================================
  59. // CLASS: CVCPPShellApp            FUNCTION: <constructor>()
  60. //---------------------------------------------------------------------------
  61. // Note: This function was built by the MFC AppWizard.
  62. //===========================================================================
  63. CVCPPShellApp::CVCPPShellApp()
  64. {
  65. }
  66.  
  67. //===========================================================================
  68. // CLASS: CVCPPShellApp            FUNCTION: InitInstance()
  69. //---------------------------------------------------------------------------
  70. // Note: This function was built by the MFC AppWizard.
  71. //===========================================================================
  72. BOOL CVCPPShellApp::InitInstance()
  73. {
  74.     // Standard initialization
  75.     // If you are not using these features and wish to reduce the size
  76.     //  of your final executable, you should remove from the following
  77.     //  the specific initialization routines you do not need.
  78.  
  79.     CVCPPShellDlg dlg;
  80.     m_pMainWnd = &dlg;
  81.     int nResponse = dlg.DoModal();
  82.     if (nResponse == IDOK)
  83.     {
  84.         //  Place code here to handle when the dialog is
  85.         //  dismissed with OK
  86.     }
  87.     else if (nResponse == IDCANCEL)
  88.     {
  89.         //  Place code here to handle when the dialog is
  90.         //  dismissed with Cancel
  91.     }
  92.  
  93.     // Since the dialog has been closed, return FALSE so that we exit the
  94.     //  application, rather than start the application's message pump.
  95.     return FALSE;
  96. }
  97.  
  98. //===========================================================================
  99. //===========================================================================
  100. // CLASS: CVCPPShellDlg
  101. //===========================================================================
  102. //===========================================================================
  103.  
  104. //===========================================================================
  105. // CLASS: CVCPPShellDlg            FUNCTION: <constructor>(CWnd*)
  106. //---------------------------------------------------------------------------
  107. // Note: This function was built by the MFC AppWizard.
  108. //===========================================================================
  109. CVCPPShellDlg::CVCPPShellDlg(CWnd* pParent /*=NULL*/)
  110.     : CDialog(CVCPPShellDlg::IDD, pParent)
  111. {
  112.     //{{AFX_DATA_INIT(CVCPPShellDlg)
  113.  
  114.     //}}AFX_DATA_INIT
  115.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  116.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  117.  
  118. }
  119.  
  120. //===========================================================================
  121. // CLASS: CVCPPShellDlg            FUNCTION: DoDataExchange(CDataExchange*)
  122. //---------------------------------------------------------------------------
  123. // Note: This function was built by the MFC AppWizard.
  124. //===========================================================================
  125. void CVCPPShellDlg::DoDataExchange(CDataExchange* pDX)
  126. {
  127.     CDialog::DoDataExchange(pDX);
  128.     //{{AFX_DATA_MAP(CVCPPShellDlg)
  129.     DDX_Text(pDX, IDC_TRAIN_NETWORK_REPORT, m_TrainNetwork_Report);
  130.     //}}AFX_DATA_MAP
  131. }
  132.  
  133.  
  134. //===========================================================================
  135. // CLASS: CVCPPShellDlg            FUNCTION: FillArrayFromFile(LPCTSTR, int, int)
  136. //===========================================================================
  137. float *CVCPPShellDlg::FillArrayFromFile(LPCTSTR fName, int numRows, int numCols)
  138. {
  139.     CStdioFile fl;
  140.     LPTSTR tmpBuffer = new char [250];
  141.  
  142.     char *token;                //pointer to string tokens to extract from file strings
  143.     char *delim = " ,\t\n";        //delimiter to use for string tokenizer
  144.  
  145.     //create array to hold floating values extracted from file
  146.     long numCells = numRows * numCols;
  147.     float *retArray = (float *)calloc (numCells, sizeof (float));
  148.     int curIndx = 0;
  149.  
  150.     if (fl.Open(fName, CFile::modeRead))
  151.     {
  152.  
  153.         //read file until end is reached
  154.         while (((fl.ReadString(tmpBuffer, 250)) != NULL) && ((curIndx < numCells)))
  155.         {
  156.             //tokenize string to extract floating values as strings
  157.             token = strtok (tmpBuffer, delim);
  158.  
  159.             while (token != NULL)
  160.             {
  161.                 //convert token to float and store in array
  162.                 retArray[curIndx] = (float) atof (token);
  163.                 curIndx++;
  164.  
  165.                 //tokenize string to extract floating values as strings
  166.                 token = strtok (NULL, delim);
  167.  
  168.             } //end token while
  169.  
  170.  
  171.         } //end fl.Open while
  172.  
  173.         fl.Close();
  174.     } //end if
  175.  
  176.     free (tmpBuffer);
  177.  
  178.     return retArray;
  179. } //end FillArrayFromFile
  180.  
  181.  
  182. //===========================================================================
  183. // CLASS: CVCPPShellDlg            MESSAGE MAP
  184. //---------------------------------------------------------------------------
  185. // Note: This mapping was built by the MFC AppWizard.
  186. //===========================================================================
  187. BEGIN_MESSAGE_MAP(CVCPPShellDlg, CDialog)
  188.     //{{AFX_MSG_MAP(CVCPPShellDlg)
  189.     ON_WM_PAINT()
  190.     ON_WM_QUERYDRAGICON()
  191.     ON_BN_CLICKED(IDC_GET_NETWORK_OUTPUT, OnGetResponse)
  192.     ON_BN_CLICKED(IDC_TRAIN_NETWORK, OnTrainNetwork)
  193.     //}}AFX_MSG_MAP
  194. END_MESSAGE_MAP()
  195.  
  196.  
  197. //===========================================================================
  198. // CLASS: CVCPPShellDlg            FUNCTION: OnInitDialog()
  199. //---------------------------------------------------------------------------
  200. // Note: This function was built by the MFC AppWizard.
  201. //===========================================================================
  202. BOOL CVCPPShellDlg::OnInitDialog()
  203. {
  204.  
  205.     CDialog::OnInitDialog();
  206.  
  207.     // Set the icon for this dialog.  The framework does this automatically
  208.     // when the application's main window is not a dialog
  209.     SetIcon(m_hIcon, TRUE);            // Set big icon
  210.     SetIcon(m_hIcon, FALSE);        // Set small icon
  211.  
  212.     //dispaly initial message in Get Network Output Report edit box
  213.     CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
  214.     pGetNetworkOutputReportEditBox->SetWindowText(_T("Not tested."));
  215.  
  216.     //disables training if the DLL only supports a recall network
  217.     if (RECALL_ONLY_NETWORK)
  218.     {
  219.             //disable Train Network button
  220.             CWnd *pTrainNetworkButton = (CWnd *) GetDlgItem (IDC_TRAIN_NETWORK);
  221.             pTrainNetworkButton->EnableWindow(FALSE);
  222.  
  223.             //disable Reset Network Before Training check box
  224.             CButton *pResetNetworkCheckBox = (CButton *) GetDlgItem (IDC_RESET_NETWORK);
  225.             pResetNetworkCheckBox->EnableWindow(FALSE);
  226.  
  227.             //dispaly initial message in Train Network Report edit box
  228.             CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
  229.             pTrainNetworkReportEditBox->SetWindowText(_T("Only Recall DLL Supported."));
  230.  
  231.             m_TrainNetwork_Report = _T("Recall Network Only.");
  232.     }
  233.     else
  234.     {
  235.             //dispaly initial message in Train Network Report edit box
  236.             CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
  237.             pTrainNetworkReportEditBox->SetWindowText(_T("Not tested."));
  238.  
  239.             m_TrainNetwork_Report = _T("Not tested.");
  240.     }
  241.  
  242.     return TRUE;  // return TRUE  unless you set the focus to a control
  243. }
  244.  
  245. //===========================================================================
  246. // CLASS: CVCPPShellDlg            FUNCTION: OnPaint()
  247. //---------------------------------------------------------------------------
  248. // Note: This function was built by the MFC AppWizard.
  249. //---------------------------------------------------------------------------
  250. // If you add a minimize button to your dialog, you will need the code below
  251. //  to draw the icon.  For MFC applications using the document/view model,
  252. //  this is automatically done for you by the framework.
  253. //===========================================================================
  254. void CVCPPShellDlg::OnPaint()
  255. {
  256.     if (IsIconic())
  257.     {
  258.         CPaintDC dc(this); // device context for painting
  259.  
  260.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  261.  
  262.         // Center icon in client rectangle
  263.         int cxIcon = GetSystemMetrics(SM_CXICON);
  264.         int cyIcon = GetSystemMetrics(SM_CYICON);
  265.         CRect rect;
  266.         GetClientRect(&rect);
  267.         int x = (rect.Width() - cxIcon + 1) / 2;
  268.         int y = (rect.Height() - cyIcon + 1) / 2;
  269.  
  270.         // Draw the icon
  271.         dc.DrawIcon(x, y, m_hIcon);
  272.     }
  273.     else
  274.     {
  275.         CDialog::OnPaint();
  276.     }
  277. }
  278.  
  279. //===========================================================================
  280. // CLASS: CVCPPShellDlg            FUNCTION: OnQueryDragIcon()
  281. //---------------------------------------------------------------------------
  282. // Note: This function was built by the MFC AppWizard.
  283. //---------------------------------------------------------------------------
  284. // The system calls this to obtain the cursor to display while the user drags
  285. //  the minimized window.
  286. //===========================================================================
  287. HCURSOR CVCPPShellDlg::OnQueryDragIcon()
  288. {
  289.     return (HCURSOR) m_hIcon;
  290. }
  291.  
  292. //===========================================================================
  293. // CLASS: CVCPPShellDlg            FUNCTION: OnGetResponse()
  294. //---------------------------------------------------------------------------
  295. //  This function illustrates how the DLL generated by the Custom Solution
  296. //  Wizard can be used for getting the network response (output).
  297. //  Step by step instructions are given on how to use the generated DLL
  298. //  for this purpose.  Read through comments carefully performing all of the
  299. //  REQUIRED ACTIONs as you get to them.
  300. //===========================================================================
  301. void CVCPPShellDlg::OnGetResponse()
  302. {
  303.     //---------------------------------------------------------------------------
  304.     // Step 1: Create an instance of NSRecallNetwork.
  305.     //---------------------------------------------------------------------------
  306.     // IMPLEMENTATION NOTES: The DLL_PATH_NAME is defined in Globals.h
  307.     //---------------------------------------------------------------------------
  308.     // Following this call, IsInitialized() should return true.
  309.     // If IsInitialized() is false, check to make sure the path to the DLL is correct.
  310.     //---------------------------------------------------------------------------
  311.     // You could create an NSLearningNetwork object instead, if you have the
  312.     // Developers level of the Custom Solution Wizard and used it along with a
  313.     // NeuroSolutions breadboard capable of learning to generate the DLL.
  314.     // Both NSRecallNetwork and NSLearningNetwork support recall operations.
  315.     //---------------------------------------------------------------------------
  316.     NSRecallNetwork nn(DLL_PATH_NAME);
  317.  
  318.     if (nn.IsInitialized())
  319.     {
  320.         //---------------------------------------------------------------------------
  321.         // Step 2: Get the size of the DLL (number of inputs and outputs)
  322.         //---------------------------------------------------------------------------
  323.         int inputs;
  324.         int outputs;
  325.         nn.GetInputOutputInfo(inputs,outputs);
  326.  
  327.         //---------------------------------------------------------------------------
  328.         // Step 3: Load the initial network weights.
  329.         //---------------------------------------------------------------------------
  330.         // IMPLEMENTATION NOTES: The BEST_WEIGHTS_PATH_NAME is defined in Globals.h.
  331.         // The initial best weights file is an exact copy of the weights file that was
  332.         // saved when the DLL was generated. However, the best weights file will change
  333.         // with each run of the TrainNetwork function if the network is reset before
  334.         // training.
  335.         //---------------------------------------------------------------------------
  336.         nn.LoadWeights(BEST_WEIGHTS_PATH_NAME);
  337.  
  338.         //---------------------------------------------------------------------------
  339.         // Step 4: Define the input data.
  340.         //---------------------------------------------------------------------------
  341.         // IMPLEMENTATION NOTES: The following loads the training input data from your initial
  342.         // network configuration into the array inputData.
  343.         // Note that the number of inputs in the input data must match the number of inputs
  344.         // expected by the generated DLL.  Also, there can be any number of exemplars in the
  345.         // input data as long as the number of exemplars in the input data matches the number
  346.         // of exemplars in the desired data. In this case, NUMBER_OF_EXEMPLARS is defined in
  347.         // Globals.h.
  348.         //---------------------------------------------------------------------------
  349.         float *inputData = FillArrayFromFile(INPUT_FILE_PATH_NAME, inputs, NUMBER_OF_EXEMPLARS);
  350.  
  351.         //---------------------------------------------------------------------------
  352.         // Step 5: Declare the storage for the response.
  353.         //---------------------------------------------------------------------------
  354.         // IMPLEMENTATION NOTES : The dimensions of the outputData array have been set
  355.         // to match the expected size of the output data.
  356.         //---------------------------------------------------------------------------
  357.         // Note: The first dimension of the outputData array is sized according
  358.         // to the number of outputs in the DLL. The second dimension of the outputData
  359.         // array is sized according to the number of exemplars in your data set as
  360.         // defined in Globals.h.
  361.         //---------------------------------------------------------------------------
  362.         float *outputData = (float *) calloc (outputs * NUMBER_OF_EXEMPLARS, sizeof (float));
  363.  
  364.         //---------------------------------------------------------------------------
  365.         // Step 6: Get the network response to the input data.
  366.         //---------------------------------------------------------------------------
  367.         // IMPLEMENTATION NOTES: NUMBER_OF_EXEMPLARS is defined in Globals.h.
  368.         //---------------------------------------------------------------------------
  369.         nn.GetResponse(NUMBER_OF_EXEMPLARS, inputData, outputData);
  370.  
  371.         //---------------------------------------------------------------------------
  372.         // Step 7: Verify the results. (Optional)
  373.         //---------------------------------------------------------------------------
  374.         // IMPLEMENTATION NOTES: Outputs the results to the Get Network Output Report edit box
  375.         //---------------------------------------------------------------------------
  376.         // Prepare edit box for output -> clear its contents.
  377.         CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
  378.         pGetNetworkOutputReportEditBox->SetWindowText(_T(""));
  379.  
  380.         CString outStr = "Exemplar #\t";
  381.  
  382.         // Add labels to top of edit box
  383.         for (int i = 1; i <= outputs; i++)
  384.         {
  385.             CString iAsStr;
  386.             iAsStr.Format ("%d    \t", i);
  387.             outStr += "Output" + iAsStr;
  388.         }
  389.         outStr += "\r\n";
  390.  
  391.         // Show outputs for all up to 1000 exemplars
  392.         int maxExemplars = (NUMBER_OF_EXEMPLARS > 1000)?1000:NUMBER_OF_EXEMPLARS;
  393.         for (int j = 0; j < maxExemplars; j++)
  394.         {
  395.             CString jAsStr;
  396.             jAsStr.Format("%d\t\t", j + 1);
  397.             outStr += jAsStr;
  398.  
  399.             for (int k = 0; k < outputs; k++)
  400.             {
  401.                 CString resultAsString;
  402.                 resultAsString.Format("%9f\t", outputData[(j * outputs) + k]);
  403.                 outStr += resultAsString;
  404.             } //end for j
  405.  
  406.             outStr += "\r\n";
  407.         } //end for i
  408.  
  409.  
  410.         pGetNetworkOutputReportEditBox->SetWindowText(_T(outStr));
  411.  
  412.         //---------------------------------------------------------------------------
  413.         // Perform some memory clean-up
  414.         //---------------------------------------------------------------------------
  415.         free (inputData);
  416.         free (outputData);
  417.  
  418.     }
  419.     //---------------------------------------------------------------------------
  420.     // If initialization failed, report any errors here.
  421.     //---------------------------------------------------------------------------
  422.     else
  423.     {
  424.         //prepare edit box for output -> reset its contents
  425.         CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
  426.         pGetNetworkOutputReportEditBox->SetWindowText(_T("DLL Load Failed."));
  427.     }
  428.  
  429.     //---------------------------------------------------------------------------
  430.     // Update the dialog.
  431.     //---------------------------------------------------------------------------
  432.     UpdateData(FALSE);
  433. }
  434.  
  435. //===========================================================================
  436. // CLASS: CVCPPShellDlg            FUNCTION: OnTrainNetwork()
  437. //---------------------------------------------------------------------------
  438. //  The function trains a learning network DLL and saves the best weights
  439. //    to a specified file for later use.
  440. //  Step by step instructions are given on how to use the generated DLL
  441. //  for this purpose.  Read through comments carefully. The IMPLEMENTATION NOTES
  442. //  highlight parameters that you may wish to change in the future.
  443. //---------------------------------------------------------------------------
  444. //    NOTE: This subroutine only applys to users of the Developers level of the
  445. //    Custom Solution Wizard.  The Developers level allows the user to generate
  446. //    learning DLLs, whereas all other levels can only generate recall DLLs.
  447. //===========================================================================
  448. void CVCPPShellDlg::OnTrainNetwork()
  449. {
  450.  
  451.     //---------------------------------------------------------------------------
  452.     // Update Train Network Report edit box to indicate that the network is training.
  453.     //---------------------------------------------------------------------------
  454.     CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
  455.     pTrainNetworkReportEditBox->SetSel(0, -1, FALSE);
  456.     pTrainNetworkReportEditBox->ReplaceSel("Training...", FALSE);
  457.  
  458.     //---------------------------------------------------------------------------
  459.     // Step 1: Create an instance of NSLearningNetwork.
  460.     //---------------------------------------------------------------------------
  461.     // IMPLEMENTATION NOTES: The path of the DLL is defined in Globals.h.
  462.     //---------------------------------------------------------------------------
  463.     // Following this call, IsInitialized() should return true.
  464.     // If IsInitialized() is false, one of the following errors occured:
  465.     //        * The path to the DLL is incorrect.  IsLoaded() will be false.
  466.     //        * The path points a recall DLL.  IsLoaded() will be true.
  467.     //---------------------------------------------------------------------------
  468.     // Note: This step will fail if you are not using the Developers level of
  469.     // the Custom Solution Wizard or if you generated the DLL using a recall
  470.     // NeuroSolutions breadboard.
  471.     //---------------------------------------------------------------------------
  472.     NSLearningNetwork nn(DLL_PATH_NAME);
  473.  
  474.     if (nn.IsInitialized())
  475.     {
  476.         //---------------------------------------------------------------------------
  477.         // Step 2: Get the size of the DLL (number of inputs and outputs)
  478.         //---------------------------------------------------------------------------
  479.         int inputs;
  480.         int outputs;
  481.         nn.GetInputOutputInfo(inputs,outputs);
  482.  
  483.         //---------------------------------------------------------------------------
  484.         // Step 3: Load the initial network weights. (Optional)
  485.         //---------------------------------------------------------------------------
  486.         // IMPLEMENTATION NOTES: The WEIGHTS_PATH_NAME has been defined in Globals.h to
  487.         // reflect that of the weights file that was saved when the DLL was generated.
  488.         //---------------------------------------------------------------------------
  489.         // Note: This step is not necessary. If this step is not performed, the
  490.         // network will simply start with random initial weights.
  491.         //---------------------------------------------------------------------------
  492.         nn.LoadWeights(WEIGHTS_PATH_NAME);
  493.  
  494.         //---------------------------------------------------------------------------
  495.         // Resets the network (randomizes the network weights, etc.) if the user has so
  496.         // indicated by checking the "Reset Network Before Training" check box
  497.         //---------------------------------------------------------------------------
  498.         CButton *pResetNetworkCheckBox = (CButton *) GetDlgItem (IDC_RESET_NETWORK);
  499.         if (pResetNetworkCheckBox->GetCheck() == 1)
  500.             nn.ResetNetwork();
  501.  
  502.         //---------------------------------------------------------------------------
  503.         // Step 4: Define the input data.
  504.         //---------------------------------------------------------------------------
  505.         // IMPLEMENTATION NOTES: The following loads the training input data from your initial
  506.         // network configuration into the array inputData.
  507.         // Note that the number of inputs in the input data must match the number of inputs
  508.         // expected by the generated DLL.  Also, there can be any number of exemplars in the
  509.         // input data as long as the number of exemplars in the input data matches the number
  510.         // of exemplars in the desired data. In this case, NUMBER_OF_EXEMPLARS is defined in
  511.         // Globals.h.
  512.         //---------------------------------------------------------------------------
  513.         float *inputData = FillArrayFromFile(INPUT_FILE_PATH_NAME, inputs, NUMBER_OF_EXEMPLARS);
  514.  
  515.         //---------------------------------------------------------------------------
  516.         // Step 5: Define the desired data.
  517.         //---------------------------------------------------------------------------
  518.         // IMPLEMENTATION NOTES: The following loads the training desired data from your initial
  519.         // network configuration into the array desiredData.
  520.         // Note that the number of outputs in the desired data must match the number of outputs
  521.         // expected by the generated DLL.  Also, there can be any number of exemplars in the
  522.         // desired data as long as the number of exemplars in the desired data matches the number
  523.         // of exemplars in the input data. In this case, NUMBER_OF_EXEMPLARS is defined in
  524.         // Globals.h.
  525.         //---------------------------------------------------------------------------
  526.         float *desiredData = FillArrayFromFile(DESIRED_FILE_PATH_NAME, outputs, NUMBER_OF_EXEMPLARS);
  527.  
  528.         //---------------------------------------------------------------------------
  529.         // Step 6: Enable the automatic saving of the best weights. (Optional)
  530.         //---------------------------------------------------------------------------
  531.         // Note: This step is not necessary.  The default value of this property is
  532.         // always False.  Setting it to True will cause the best network weights to be
  533.         // saved during training.  If this property is set to True, be sure to call
  534.         // SetBestWeightsPathName() to set a valid path for the best weights (See Step 7).
  535.         //---------------------------------------------------------------------------
  536.         nn.SetSaveBestWeightsEnabled(true);
  537.  
  538.         //---------------------------------------------------------------------------
  539.         // Step 7: Set the path for saving the best weights. (Optional)
  540.         //---------------------------------------------------------------------------
  541.         // IMPLEMENTATION NOTES : The BEST_WEIGHTS_PATH_NAME is defined in Globals.h.
  542.         //---------------------------------------------------------------------------
  543.         // Note: The specified path will be used for saving the best weights during
  544.         // training.  This SetBestWeightsPathName() function must be set to a
  545.         // valid path if SetSaveBestWeightsEnabled() has been set to true.  Otherwise,
  546.         // setting this property is optional.
  547.         //---------------------------------------------------------------------------
  548.         nn.SetBestWeightsPathName(BEST_WEIGHTS_PATH_NAME);
  549.  
  550.         //---------------------------------------------------------------------------
  551.         // Step 8: Train the network.
  552.         //---------------------------------------------------------------------------
  553.         // IMPLEMENTATION NOTES : The NUMBER_OF_EPOCHS and NUMBER_OF_EXEMPLARS are defined
  554.         // in Globals.h and have been determined from the initial network configuration.
  555.         //---------------------------------------------------------------------------
  556.         // Note: Two versions of the Train() function are provided.  This version does
  557.         // not include cross validation parameters.  If cross validation is desired,
  558.         // use the other version of Train() and call SetCrossValidationEnabled(true).
  559.         //---------------------------------------------------------------------------
  560.         nn.Train(NUMBER_OF_EPOCHS, NUMBER_OF_EXEMPLARS, inputData, desiredData);
  561.  
  562.         //---------------------------------------------------------------------------
  563.         // Step 9: Report best cost. (Optional)
  564.         //---------------------------------------------------------------------------
  565.         // This dialog-based application reports the best cost to the user.
  566.         //---------------------------------------------------------------------------
  567.         // Note: This step is not necessary, it is provided only to show how the best
  568.         // cost can be obtained.
  569.         //---------------------------------------------------------------------------
  570.         float bestCost = nn.GetBestCost();
  571.         m_TrainNetwork_Report.Format("Best Cost = %g",bestCost);
  572.  
  573.         //---------------------------------------------------------------------------
  574.         // Perform some memory clean-up
  575.         //---------------------------------------------------------------------------
  576.         free (inputData);
  577.         free (desiredData);
  578.     }
  579.  
  580.     //---------------------------------------------------------------------------
  581.     // If initialization failed, report any errors here.
  582.     //---------------------------------------------------------------------------
  583.     else
  584.     {
  585.         //---------------------------------------------------------------------------
  586.         // If the DLL was loaded, this is probably a recall-only network.
  587.         //---------------------------------------------------------------------------
  588.         if (nn.IsLoaded())
  589.         {
  590.             m_TrainNetwork_Report = "DLL recall only.";
  591.         }
  592.         //---------------------------------------------------------------------------
  593.         // Else, the DLL was not loaded, the path is probably incorrect.
  594.         //---------------------------------------------------------------------------
  595.         else
  596.         {
  597.             m_TrainNetwork_Report = "DLL load failed.";
  598.         }
  599.     }
  600.  
  601.     //---------------------------------------------------------------------------
  602.     // Update the dialog.
  603.     //---------------------------------------------------------------------------
  604.     UpdateData(FALSE);
  605. }
  606.  
  607.